/**
 * 认证工具类
 * 提供token管理、登录状态检查等功能
 */
import storage from './storage'
import router from '@/router'
import {refreshToken} from '@/api/user'

let tokenCheckInterval = null;

const auth = {
  /**
   * 检查token是否过期
   * @returns {boolean} - token是否已过期
   */
  checkTokenExpiration() {
    const token = storage.get('token')

    if (!token || !token.expiresAt) {
      return true // 没有token或没有过期时间，视为过期
    }

    // 检查token是否过期（减少缓冲期，避免误判）
    const now = Date.now()
    const expiresAt = new Date(token.expiresAt).getTime()
    return now > expiresAt - 5000 // 改为5秒缓冲期，减少误判
  },

  /**
   * 启动token过期检查
   * 每分钟检查一次token是否即将过期，如果即将过期且用户勾选了记住登录，则自动刷新
   */
  startTokenExpirationCheck() {
    // 清除之前的定时器
    if (tokenCheckInterval) {
      clearInterval(tokenCheckInterval)
    }

    // 每分钟检查一次
    tokenCheckInterval = setInterval(async () => {
      const token = storage.get('token')
      const rememberFlag = localStorage.getItem('rememberFlag')
      
      if (!token || !token.expiresAt) {
        return
      }

      const now = Date.now()
      const expiresAt = new Date(token.expiresAt).getTime()
      const timeUntilExpiry = expiresAt - now
      
      // 如果token在5分钟内过期，且用户勾选了记住登录，则自动刷新
      if (timeUntilExpiry < 300000 && timeUntilExpiry > 0 && rememberFlag === 'true') {
        try {
          const res = await refreshToken({ refreshToken: token.refreshToken })
          if (res && res.accessToken) {
            // 解析新token的过期时间
            let newExpiresAt;
            try {
              if (res.accessToken) {
                const tokenParts = res.accessToken.split('.');
                if (tokenParts.length >= 2) {
                  const base64Url = tokenParts[1];
                  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
                  const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
                    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
                  }).join(''));
                  const jwtPayload = JSON.parse(jsonPayload);
                  if (jwtPayload.exp) {
                    newExpiresAt = new Date(jwtPayload.exp * 1000).toISOString();
                  }
                }
              }
            } catch (parseError) {
              console.error('解析JWT失败:', parseError)
            }
            
            // 更新token
            const newToken = { ...token, ...res, expiresAt: newExpiresAt }
            storage.set('token', newToken)
            localStorage.setItem('accessToken', res.accessToken)
            localStorage.setItem('refreshToken', res.refreshToken)
            
          }
        } catch (error) {
          console.error('自动刷新token失败:', error)
        }
      }
    }, 60000) // 每分钟检查一次
  },

  /**
   * 停止token过期检查
   */
  stopTokenExpirationCheck() {
    if (tokenCheckInterval) {
      clearInterval(tokenCheckInterval)
      tokenCheckInterval = null
    }
  },

  /**
   * 自动登出
   * 清除本地存储并跳转到登录页面
   */
  async logout(showMessage = true) {
    try {
      const token = storage.get('token')
      const rememberFlag = localStorage.getItem('rememberFlag')
      
      // 如果记住登录，尝试刷新token
      if (rememberFlag === 'true' && token && token.refreshToken) {
        try {
          const res = await refreshToken({ refreshToken: token.refreshToken })
          if (res && res.accessToken) {
            // 解析新token的过期时间
            let expiresAt;
            try {
              if (res.accessToken) {
                const tokenParts = res.accessToken.split('.');
                if (tokenParts.length >= 2) {
                  const base64Url = tokenParts[1];
                  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
                  const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
                    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
                  }).join(''));
                  const jwtPayload = JSON.parse(jsonPayload);
                  if (jwtPayload.exp) {
                    expiresAt = new Date(jwtPayload.exp * 1000).toISOString();
                  }
                }
              }
            } catch (parseError) {
              console.error('解析JWT失败:', parseError)
            }
            
            // 更新token
            const newToken = { ...token, ...res, expiresAt }
            storage.set('token', newToken)
            localStorage.setItem('accessToken', res.accessToken)
            localStorage.setItem('refreshToken', res.refreshToken)
            
            if (showMessage) {
              // 导入ElMessage
              const { ElMessage } = await import('element-plus')
              ElMessage.success('Token已自动刷新，继续使用中...')
            }
            return // 刷新成功，不跳转登录页
          }
        } catch (error) {
          console.error('自动刷新token失败:', error)
          // 刷新失败，继续登出流程
        }
      }
      
      // 清除token
      storage.remove('token')
      localStorage.removeItem('accessToken')
      localStorage.removeItem('refreshToken')
      localStorage.removeItem('userInfo')
      
      // 停止token检查
      this.stopTokenExpirationCheck()
      
      if (showMessage) {
        // 导入ElMessage
        const { ElMessage } = await import('element-plus')
        ElMessage.warning('登录已过期，请重新登录')
      }
      
      // 跳转到登录页
      router.push('/login')
    } catch (error) {
      console.error('登出失败:', error)
      router.push('/login')
    }
  },

  /**
   * 检查登录状态
   * 如果token过期，则自动登出
   * @returns {boolean} - 是否已登录且token有效
   */
  checkLoginStatus() {
    // 获取当前路由路径
    const currentPath = window.location.pathname;
    const publicPages = ['/login', '/register', '/forgot'];
    
    // 如果是公开页面，不进行检查
    if (publicPages.includes(currentPath)) {
      return true;
    }
    
    if (this.checkTokenExpiration()) {
      this.logout(false); // 不显示提示信息，避免重复提示
      return false;
    }
    
    // 如果token有效，启动过期检查
    this.startTokenExpirationCheck();
    return true;
  },

  /**
   * 调试方法：获取token状态信息
   * @returns {Object} - token状态信息
   */
  getTokenStatus() {
    const token = storage.get('token');
    const now = Date.now();
    
    if (!token || !token.expiresAt) {
      return {
        hasToken: false,
        hasExpiresAt: false,
        isExpired: true,
        timeUntilExpiry: 0,
        expiresAt: null,
        now: new Date(now).toISOString()
      };
    }
    
    const expiresAt = new Date(token.expiresAt).getTime();
    const timeUntilExpiry = expiresAt - now;
    const isExpired = timeUntilExpiry <= 5000; // 5秒缓冲期
    
    return {
      hasToken: true,
      hasExpiresAt: true,
      isExpired,
      timeUntilExpiry,
      expiresAt: new Date(expiresAt).toISOString(),
      now: new Date(now).toISOString()
    };
  }
}

export default auth